import json
from django.db import transaction
from django.shortcuts import render
from django.views import View
from django import http
from houses.models import Area, House, Facility, HouseImage
from ihome_01.libs.qiniuyun.qiniu_storage import storage
from ihome_01.settings.dev import QINIUYUN_URL
from ihome_01.utils import constants
from ihome_01.utils.my_file_type import image_file
from ihome_01.utils.my_loginview import LoginRequiredView
from ihome_01.utils.response import RET
from orders.models import Order
from users.models import User


# 获取城区列表信息
class AreasView(View):
    def get(self,request):
        data_list = []
        areas = Area.objects.all()
        for area in areas:
            item_dict = {"aid":area.id,
                         "aname": area.name,
                         }
            data_list.append(item_dict)
        return http.JsonResponse({"errno": RET.OK, "errmsg": "获取成功", "data": data_list})


# 获取房源信息
class UserHousesView(LoginRequiredView):
    def get(self,request):
        # 1. 获取参数
        cookie_mobile = request.COOKIES.get("username")
        try:
            user = User.objects.get(mobile=cookie_mobile)
            houses = House.objects.filter(user=user).all()
        except Exception as e:
            return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库查询失败"})

        houses_list = []
        if houses.count():
            for house in houses:
                house ={"house_id":house.id,
                        "title":house.title,
                        "img_url":QINIUYUN_URL + house.index_image_url,
                        "area_name":house.area.name,
                        "price":house.price *100,
                        "ctime":house.create_time,
                        }
                houses_list.append(house)
        else:
            houses_list = [{}]

        data = {"houses":houses_list}
        return http.JsonResponse({"errno": RET.OK, "errmsg": "获取成功", "data": data})


# 发布新房源
class NewHousesView(LoginRequiredView):
    def post(self,request):
        # 1. 获取参数
        data_dict = json.loads(request.body.decode())
        title = data_dict.get("title")  # 房屋标题
        price = data_dict.get("price")  # 房屋单价
        area_id = int(data_dict.get("area_id")) # 城区id
        address = data_dict.get("address")  # 详细地址
        room_count = data_dict.get("room_count")  # 房间数目
        acreage = data_dict.get("acreage")  # 房屋面积
        unit = data_dict.get("unit")  # 房屋类型单元， 如几室几厅
        capacity = data_dict.get("capacity")  # 房屋容纳的人数
        beds = data_dict.get("beds")  # 房屋床铺的配置
        deposit = data_dict.get("deposit")  # 房屋押金
        min_days = data_dict.get("min_days")  # 最少入住天数
        max_days = data_dict.get("max_days")  # 最多入住天数，0表示不限制

        # 2. 校验数据
        # 2.1 为空校验
        if not all([title, price, area_id,address,room_count,acreage,unit,capacity,beds,deposit,min_days,max_days]):
            return http.JsonResponse({"errno": RET.NECESSARYPARAMERR, "errmsg": "参数不全"})

        # 显式的开启一个事务
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                cookie_mobile = request.COOKIES.get("username")
                user = User.objects.get(mobile=cookie_mobile)
                area = Area.objects.get(id=area_id)
            except Exception as e:
                # 回滚到保存点
                transaction.savepoint_rollback(save_id)
                return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库操作失败"})
            # 3. 数据入库
            house = House()
            house.user = user
            house.area = area
            house.title = title
            house.price = price
            house.address = address
            house.room_count = room_count
            house.acreage = acreage
            house.unit = unit
            house.capacity = capacity
            house.beds = beds
            house.deposit = deposit
            house.min_days = min_days
            house.max_days = max_days

            try:
                house.save()
            except Exception as e:
                # 回滚到保存点
                transaction.savepoint_rollback(save_id)
                return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库保存失败"})

            try:
                facility_ids = data_dict.get("facility")  # 设施信息
                if facility_ids:
                    facilities = Facility.objects.filter(id__in=facility_ids)
                    for facility in facilities:
                        house.facility.add(facility)
            except Exception as e:
                # 回滚到保存点
                transaction.savepoint_rollback(save_id)
                return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库保存失败"})
            # 提交订单成功，显式的提交一次事务
            transaction.savepoint_commit(save_id)
        data = {"house_id":house.id}
        return http.JsonResponse({"errno": RET.OK, "errmsg": "发布成功", "data": data})


# 上传新房源图片
class NewHousesImagesView(LoginRequiredView):
    def post(self,request,house_id):
        # 1. 获取参数
        house_image = request.FILES.get("house_image")

        # 2. 校验参数
        # 2.1 为空校验
        if not house_image:
            return http.JsonResponse({"errno": RET.PARAMERR,"errmsg": "参数错误"})

        if not image_file(house_image):
            return http.JsonResponse({"errno": RET.PARAMERR,"errmsg": "图片格式错误"})

        # 读取出文件对象的二进制数据
        file_data = house_image.read()

        # 将图片上传到千牛云
        try:
            key = storage(file_data)
        except Exception as e:
            return http.JsonResponse({"errno": RET.THIRDERR, "errmsg": "上传图片失败"})

        # 将千牛云上传的图片地址保存到数据库
        cookie_mobile = request.COOKIES.get("username")
        try:
            user = User.objects.get(mobile=cookie_mobile)
            house = House.objects.get(user=user,id=int(house_id))
            if not house.index_image_url:
                house.index_image_url = key
                house.save()
            house_images = HouseImage.objects.create(house=house, url=key)
        except Exception as e:
            return http.JsonResponse({"errno": RET.DBERR, "errmsg": "上传数据库失败"})

        # 3. 拼接数据，返回响应
        data = {"user_id": user.id,
                "url": QINIUYUN_URL + house_images.url,
                }

        return http.JsonResponse({"errno": RET.OK, "errmsg": "图片上传成功","data":data})

# 获取首页轮播图片
class HousesIndexView(View):
    def get(self,request):
        houses_list = House.objects.order_by("-order_count").all()[:constants.INDEX_IMAGE_COUNT]
        data = []
        for house in houses_list:
            if not house.index_image_url:
                continue
            house_dict = {"house_id":house.id,
                          "title":house.title,
                          "img_url":QINIUYUN_URL + house.index_image_url,
                          }
            data.append(house_dict)

        return http.JsonResponse({"errno": RET.OK, "errmsg": "OK","data":data})


# 获取房屋的详细信息
class HousesDetailView(LoginRequiredView):
    def get(self,request,house_id):
        try:
            house = House.objects.get(id=house_id)
        except Exception as e:
            return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库查询失败"})

        # 获取房屋图片
        image_list = []
        try:
            house_images = HouseImage.objects.filter(house=house).all()
        except Exception as e:
            return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库查询失败"})
        for image in house_images:
            image_url = QINIUYUN_URL + image.url
            image_list.append(image_url)

        # 获取房屋设备
        facilities_list = []
        facilities = house.facility.all()
        for facility in facilities:
            facilities_list.append(facility.id)

        # 获取评论信息
        comments_list = []
        if house.order_count:
            try:
                house_comments = Order.objects.filter(house=house).all()
            except Exception as e:
                return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库查询失败"})
            if house_comments:
                for comment in house_comments:
                    comment_dict = {"user_name":comment.user,"ctime":comment.create_time,"comment":comment.comment}
                    comments_list.append(comment_dict)
        else:
            comments_list = [{"user_name":None,"ctime":None,"comment":None}]

        # 获取用户资料
        cookie_mobile = request.COOKIES.get("username")
        try:
            user = User.objects.get(mobile=cookie_mobile)
        except Exception as e:
            return http.JsonResponse({"errno": RET.DBERR, "errmsg": "数据库查询失败"})

        data = {"house":{"img_urls":image_list,
                         "price":house.price*100,
                         "user_id":house.user.id,
                         "hid":house.id,
                         "title":house.title,
                         "user_avatar":QINIUYUN_URL + house.user.avatar.url,
                         "user_name":house.user.username,
                         "address":house.address,
                         "room_count":house.room_count,
                         "acreage":house.acreage,
                         "unit":house.unit,
                         "capacity":house.capacity,
                         "beds":house.beds,
                         "deposit":house.deposit*100,
                         "min_days":house.min_days,
                         "max_days":house.max_days,
                         "facilities":facilities_list,
                         "comments":comments_list,
                         },
                "user_id":user.id,
                }
        return http.JsonResponse({"errno": RET.OK, "errmsg": "OK", "data": data})